/*
 ============================================================================
 Name        pfs: pfs.c
 Author      : superacidos
 Version     :
 Copyright   : Your copyright notice
 Description : Hello World in C, Ansi-style
 ============================================================================
 */

#include <signal.h>
#include <pthread.h>
#include "interfaz.h"
#include "config.h"
#include "fat.h"
#include "pfsFuse.h"
#include "log.h"
#include "archivo.h"
#include <sys/types.h>

struct bootsector bs;
struct fatCache fat_cache;
struct stConfig config;
int32_t cantidadConexiones;
int32_t conexionesAbiertas;
pthread_mutex_t semaforoCantidadConexion;
pthread_mutex_t semaforoListaArchivos;
pthread_mutex_t semaforoFatRegion;
ARCHIVO *archivos_en_memoria;

void consola(void * args);

void tratamientoSenial(int sig)
{
	printf("%s", "\n**********ENTRO UN SIGUSR1********\n");
	//CREAR ARCHIVO CACHE.DUMP
	//POR CADA CACHE EXISTENTE
	//ESCRIBIR SU CONTENIDO EN CACHE.DUMP
	FILE *log = fopen("cache_dump.txt", "a");

	ARCHIVO *archivo;
	char linea[255];
	char fechayhora[80];
	char conversion[20];
	struct bloqueCache *bloqCache;
	int32_t i;

	//RECORRO LA LISTA Y POR CADA ARCHIVO ESCRIBO LA INFORMACION
	archivo = archivos_en_memoria;
	while(archivo != NULL)
	{

		//CALCULO HORA CON EL FORMATO APROPIADO
		char fechayhora[80];
		time_t hora = time (NULL);
		struct tm *tmPtr = localtime(&hora);
		strftime( fechayhora, 21, "%yy %mm %dd %H:%M:%S", tmPtr );


		memcpy(linea, "\nTimestamp: ", 13);
		memcpy(linea+11,fechayhora, 21);
		fputs(linea, log);

		fputs("\nTamanio de bloque de Cache: 4096\n", log);

		sprintf(linea,"Cantidad de bloques de Cache: %d ",config.bloqpercache);

		fputs(linea, log);

		bloqCache = archivo->cache;

		for(i=0;i<config.bloqpercache; i++)
		{
			sprintf(linea,"\nContenido de bloque de cache: %d \n",i);
			fputs(linea, log);
			fputs(bloqCache->data, log);

			bloqCache++;
		}

		//LEE SIGUIENTE ARCHIVO-CACHE
		archivo = (*archivo).sig;
		fputs("\n\n\n----------------------------------------------------------\n\n\n",  log );
	}

	fclose (log);
}

int32_t main(int32_t argc, char *argv[]) {

	if (signal(SIGUSR1, tratamientoSenial)==SIG_ERR)
	{
		printf("Se ha producido un error");
		exit (-1);
	}
	if(!loadConfig())
	{
		printf("Ha ocurrido un error con el archivo de configuracion.");
		if(config.loguear == 1)
		{
			int pid = getpid();
			logMessage("main",pid,gettid(),3,"Ha ocurrido un error con el archivo de configuracion");
		}

	}
	else
	{
		cantidadConexiones = atoi(config.cantidadConexiones);

		//inicializo semaforo mutex para cantidad de conexiones
		pthread_mutex_init(&semaforoCantidadConexion,NULL);
		pthread_mutex_init(&semaforoListaArchivos,NULL);

		// Initicializar parametros de la FAT
		if (!(load_bootsector()))
		{
			printf("Boot Sector: Error al cargar los parametros del Boot Sector!\r\n");
			if(config.loguear == 1)
			{
				int pid = getpid();
				logMessage("main",pid,gettid(),3,"Error al cargar los parametros del Boot Sector");
			}

		}

		//Calculo cantidad bloques-cache por cache
		config.bloqpercache = config.tamanioCache / (*bs.secperclus * BYTESPERSEC);

		//Cargar FAT Region en memoria

		if (!(fat_load(0)))
		{
			printf("Fat Region: Error al cargar en memoria!\r\n");
			if(config.loguear == 1)
			{
				int pid = getpid();
				logMessage("main",pid,gettid(),3,"Error al cargar Fat Region en memoria");
			}
		}

		//inicializo semaforo mutex para Fat Region
		pthread_mutex_init(&semaforoFatRegion,NULL);


		//creo el hilo de consola

			pthread_t thread;
			pthread_create(&thread,NULL,(void*)&consola,NULL);

		int argc_fuse = 4;
		char *argv_fuse[]= {"", config.pathFS, "-d", "-f"};
		int32_t probando = fuse_init(argc_fuse, argv_fuse);


	}
	return 1;
}


void consola(void * args)
{
	//CONSOLA
	while (1)
	{
		char command[20];
		char dir[100];
		gets(dir);
		sscanf(dir, "%s", command);
		if(strstr(command, "fsinfo"))
		{
			fsinfo();
		}
		else if(strstr(command, "finfo"))
		{
			char *path;
			path = malloc(256);
			sscanf(dir, "%s %s", command, path);
			finfo(path);

			free(path);
		}
		else
		{
			printf("Instruccion invalida\n");
			if(config.loguear == 1)
			{
				int pid = getpid();
				logMessage("main",pid,gettid(),1,"Se ingreso instruccion invalida");
			}
		}
	}
}


